<template>
  <el-container class="builder">
    <div class="headerTopBar">
      <div class="one_left">
        <el-input
          v-model="baseData.title"
          maxlength="20"
          style="width:160px"
          placeholder="请输入活动标题"
          @change="titleChanged"
        />
        <el-input
          v-model="baseData.pageDot"
          style="width: 160px;margin-left:20px"
          maxlength="20"
          placeholder="只能输入英文字符"
          @change="dotChanged"
        />
      </div>

      <div class="center_inner">
        <div>
          <el-input v-model="scaleText" disabled class="input-scale">
            <el-button
              slot="prepend"
              icon="el-icon-minus"
              size="mini"
              @click="resizeScale(0)"
            />
            <el-button
              slot="append"
              size="mini"
              icon="el-icon-plus"
              @click="resizeScale(1)"
            />
          </el-input>
        </div>
      </div>
      <div class="one_right">
        <el-button type="success" icon="el-icon-success" @click="assembly('save')">
          保存
        </el-button>
        <el-button v-show="stepsl >= 2" type="info" icon="el-icon-top-left" @click="back">
          撤销
        </el-button>
        <el-button type="warning" icon="el-icon-refresh-right" @click="clearMain">
          重做
        </el-button>
        <el-button
          type="primary"
          icon="el-icon-video-camera-solid"
          style="margin-left:30px"
          @click="previewAction"
        >
          预览
        </el-button>
        <el-button
          type="primary"
          icon="el-icon-upload"
          @click="publish"
        >
          发布
        </el-button>
        <el-button
          @click="backToActivityList"
        >
          返回
        </el-button>
      </div>
    </div>
    <el-header style="display:none" class="topBar">
      <el-popover
        ref="qrpopover"
        v-model="qrpopoverVisible"
        class="previewBtn"
        placement="top-start"
        width="200"
        trigger="manual"
      >
        <div v-show="previewUrl !== ''">
          <qr-code :value="previewUrl" :size="200" />
        </div>
        <div
          style="text-align: center; cursor: pointer"
          @click="
            qrpopoverVisible = false
            previewUrl = ''
          "
        >
          关闭
        </div>
        <div v-show="previewUrl === ''" class="loadingQr">
          <i class="el-icon-loading"></i>
        </div>
      </el-popover>
    </el-header>

    <el-container id="dashboard">
      <!-- 左侧组件库 -->
      <div class="leftBar">
        <component-house :showall="true" />
      </div>
      <!-- 手机屏幕 主编辑区域 -->
      <div class="mainScreen" style="padding-top:8px">
        <main-page ref="mainpage" />
      </div>
      <!-- 样式、内容编辑器 -->
      <div class="rightBar">
        <component
          :is="selectedComponent.properties"
          v-show="showProperty === 1"
          :key="componentKey"
          :activity-code="baseData.activityCode"
          :module-code="selectedComponent._id"
        />
        <components-manager v-show="showProperty === 2" :activity-code="baseData.activityCode" />
        <page-properties-manager
          v-if="hasload && showProperty === 3"
          :activity-code="baseData.activityCode"
        />
      </div>
      <!-- <div
        v-show="showProperty === 2 && pageContent.componentList.length > 0"
        class="rightBar"
      >
        <components-manager :activity-code="baseData.activityCode" />
      </div>
      <div v-show="showProperty === 3" class="rightBar">
        <page-properties-manager
          v-if="showProperty === 3"
          :activity-code="baseData.activityCode"
        />
      </div> -->
      <div
       
        class="right-mode-block"
      >
        <div
          v-show="pageContent.componentList.length > 0"
          class="item"
          :class="{ on: 1 === showProperty, noton: showProperty !== 1 }"
          @click="changePropertyMode(1)"
        >
          <i class="el-icon-menu"></i>组件属性
        </div>
        <div
          class="item"
          :class="{ on: 2 === showProperty, noton: showProperty !== 2 }"
          @click="changePropertyMode(2)"
        >
          <i class="el-icon-tickets"></i>组件管理
        </div>
        <div
          class="item"
          :class="{ on: 3 === showProperty, noton: showProperty !== 3 }"
          @click="changePropertyMode(3)"
        >
          <i class="el-icon-mobile"></i>页面设置
        </div>
      </div>
    </el-container>
  </el-container>
</template>

<script>
import ComponentHouse from '@/components/properties/Creator/ComponentHouse'
import MainPage from '@/components/properties/Creator/MainPage'
import tool from '@/util/tool'
import validModule from '@/util/validModule'
import QrCode from '@/components/properties/Creator/QrCode'
import draggable from 'vuedraggable'
import { mapGetters, mapMutations } from 'vuex'
import {  post } from '@/servers/http'
import PageServer from '@/servers/page'
import Clipboard from 'clipboard'
import PagePropertiesManager from '@/components/properties/Creator/PagePropertiesManager'
import { editorStack } from '@/util/biz/editorStack'
import html2canvas from 'html2canvas'
import { MOBILE_PAGE_HOST } from '@/config/default'

import Vue from 'vue'
import 'element-ui/lib/theme-chalk/index.css'
import ElementUI,{ Loading } from 'element-ui'
Vue.use(ElementUI) 
Vue.use(Loading.directive)

let loadingInstance
export default {
  components: {
    PagePropertiesManager,
    ComponentHouse,
    MainPage,
    QrCode,
    draggable,
    ...editorStack,
  },
  layout: 'manageLayout',
  data () {
    return {
      hasload:false,
      statusText:'',
      sday: null,
      eday: null,
      saveTimes: 0,
      copyDialogVisible: false,
      mobileUrl: '',
      primaryPictureUrl: '',
      qrpopoverVisible: false,
      propertiesComponent: '',
      scaleText: '100%',
      loaded: false,
      toolbar: {
        cancel: require('@/assets/image/toolbar/cancel.png'),
        preview: require('@/assets/image/toolbar/preview.png'),
        redo: require('@/assets/image/toolbar/redo.png'),
        save: require('@/assets/image/toolbar/save.png'),
        publish: require('@/assets/image/toolbar/publish.png'),
      },
      rules: {
        title: [{ required: true, message: '请输入活动标题', trigger: 'blur' }],
        pageDot: [
          { required: true, message: '请输入页面打点', trigger: 'blur' },
        ],
      },
      baseData: {
        title: '',
        pageDot: '',
        activityCode: '',
      },
      pages: [],
      drag: false,
      previewUrl: '',
      componentKey: 0,

      lastData:''
    }
  },
  computed: {
    ...mapGetters('step', ['steps']),
    ...mapGetters('main', ['pageContent', 'selectedConfigBlock','selectedComponent','bizData']),
    stepsl () {
      return this.steps.length
    },
    showProperty(){
      return this.selectedConfigBlock
    }
  },
  watch: {
    'selectedComponent._id' () {
      this.componentKey++
    },
  },
  created () {
    this.baseData.activityCode = tool.getUrlParam('activityCode')
    this.resetPage()
  },
  beforeMount () {
    document.querySelector('body').setAttribute('class', 'black')
  },
  mounted () {
    
    if (tool.getUrlParam('type') === '1') {
     
      this.renderByActivityCode()
    } else {
      this.hasload=true
      this.lastData =JSON.stringify(this.pageContent)
    }
    this.initCopy()
  },
  methods: {
    ...mapMutations('step', [
      'stepsAdd1',
      'stepsRemove1',
      'stepsEmpty',
      'stepLock',
    ]),
    ...mapMutations('main', [
      'resetPage',
      'editPage',
      'setPageContent',
      'selectComponent',
      'setIsSaving',
      'changeSelectedConfigBlock'
    ]),
    changePropertyMode (value) {
      // this.showProperty = value
      this.changeSelectedConfigBlock(value)
    },
    initCopy () {
      let _this = this
      let clipboard = new Clipboard('.copyBtn', {
        text: function () {
          return _this.mobileUrl ? _this.mobileUrl : '还没有发布！'
        },
      })
      clipboard.on('success', () => {
        _this.$message({
          type: 'success',
          message: '复制成功!',
        })
      })
      clipboard.on('error', () => {
        console.log('该浏览器不支持自动复制')
      })
    },
    backToActivityList () {
      console.log(this.lastData)
      console.log('===================================')
      console.log(JSON.stringify(this.pageContent))
      
      if (this.lastData!==JSON.stringify(this.pageContent)){
        this.$confirm('数据未保存，您确定要退出活动吗?', '提示', {
          confirmButtonText: '确定并立即返回',
          cancelButtonText: '取消返回',
          type: 'warning'
        }).then(() => {
          this.doBack()
        }).catch(() => {
        
        })
      } else {
        this.doBack()
      } 
    },
    doBack(){
      let url =
        '/management/activity?from=child&itemCode=' +
        tool.getUrlParam('project') +
        '&itemName=' +
        tool.getUrlParam('itemName')+
        '&shiro_sid='+tool.getUrlParam('shiro_sid') +
        '&token=' + tool.getUrlParam('token')
        
      location.href =url
    },
    resizeScale (type) {
      let value = ''
      if (type === 0) {
        value = this.$refs.mainpage.zoomOut()
      } else {
        value = this.$refs.mainpage.zoomIn()
      }
      if (value) {
        this.scaleText = (value * 100).toFixed(0) + '%'
      }
    },
    publish(){
      if (tool.getUrlParam('type')==='0' &&  this.saveTimes===0){
        // 新增活动，未保存，不能发布
        this.$message.error('这个活动必须保存后才能发布！')
        return
      }
      
      if (this.lastData!==JSON.stringify(this.pageContent)){
        this.$confirm('数据未保存，您确定要发布活动吗?', '提示', {
          confirmButtonText: '确定并立即发布',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.doPublish()
        }).catch(() => {
        
        })
      } else {
        this.$confirm('您正在执行发布操作，确定要继续吗?', '提示', {
          confirmButtonText: '确定并立即发布',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.doPublish()
        }).catch(() => {
        
        }) 
      } 
    },
    doPublish(){
      if (this.pageContent.componentList.length===0){
        this.$message.error('活动没有任何内容！')
        return
      }
      post('/activity/synchroJsonFromDbToCdn',{ activityCode:tool.getUrlParam('activityCode') }).then(res => {
        if (res.flag!=='S'){
          this.$message.error(res.msg)
          return
        }
        this.refreshCdn()
        this.$message.info('发布成功，2分钟生效！')
      }).catch(err => {
        this.$message.error(err.message)
      })
    },
    // 根据activityCode渲染
    renderByActivityCode () {

      loadingInstance = Loading.service({
        background: 'rgba(0,0,0,0.75)',
        fullscreen: true,
        text:'加载中……',
        spinner:'el-icon-loading',
        customClass:'wait-loading'
      })

      let activityCode= tool.getUrlParam('activityCode')
      PageServer.queryDetail({
        activityCode:activityCode 
      }).then((res) => {
        if (res.flag === 'S') {
          this.baseData.title = res.data.activityTitle
          this.baseData.pageDot = res.data.pageDot
          post('/activity/getActivityJsonStrInfo',{ activityCode:activityCode }).then(res => {
            if (res.flag!=='S'){
              this.$message.error(res.msg)
              return
            }
            let content=JSON.parse(res.data)
            this.setPageContent(content)
            this.lastData=JSON.stringify(this.pageContent) 
            this.updateFields(content)
            loadingInstance.close()
            this.hasload=true
          }).catch(err => {
            this.$message.error(err.message)
            loadingInstance.close()
          })
        }
      }).catch(err => {
        loadingInstance.close()
      })
    },
    // 回退
    back () {
      let _this = this
      if (this.steps.length > 1) {
        this.stepsRemove1()
        let model = this.steps[0]
        this.setPageContent(model)

        let selectedId = this.selectedComponent._id
        if (_this.pageContent.componentList) {
          let t = _this.pageContent.componentList.find(
            (a) => a._id === selectedId
          )
          if (t) {
            _this.selectComponent(t)
          }
        }
      }
    },
    clearMain () {
      this.resetPage()
    },
    capturePic () {
      loadingInstance.text='开始截图……'
      return html2canvas(document.querySelector('.mainBg'), {
        height: 450,
        allowTaint: false,
        taintTest: true,
        useCORS: true,
        background: '#eee',
        ignoreElements:(element) => {
          // 排除不参与截图的元素
          if (element.classList.contains('increase-limit-module')){
            return true
          } else {
            return false
          }
        }
      }).catch(err => {
        console.log(err)
      })
    },
    previewAction(){
      if (this.lastData!==JSON.stringify(this.pageContent)){
        this.$confirm('数据未保存，您确定要预览吗?', '提示', {
          confirmButtonText: '确定并立即预览',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.doPreview()
        }).catch(() => {
        })
      } else {

        this.doPreview()
      }

    },
    doPreview(){
 
      let tempUrl ='/mobile?userNo=&navStyle=light&gestureAble=Y&type=preview&activityCode='
      this.previewUrl =
                MOBILE_PAGE_HOST +
                tempUrl +
                this.baseData.activityCode +
                '&rand=' +
                tool.guid()
      this.qrpopoverVisible = true
        
    },
    assembly (type) {
      let _this = this
      if (!type) return

      let list = this.pageContent.componentList
      if (list.length === 0) {
        return this.$message.error('您还没有选择组件！')
      }
      // 验证各个组件参数是否合法
      for (let fn in validModule) {
        let moduleName = fn.toString().substring(5, fn.toString().length)
        let componentList = list.filter((a) => a.code === moduleName)
        if (componentList && componentList.length > 0) {
          for (let k = 0; k < componentList.length; k++) {
            let component = componentList[k]
            let data = validModule[fn](component, list,this.bizData)
            if (!data.flag) {
              _this.$message.error(data.message)
              return
            }
          }
        }
      }

      if (!_this.baseData.title) {
        return this.$message.error('请输入活动标题！')
      }


      let re = new RegExp('^[a-zA-Z]+$')
      if (!re.test(_this.baseData.pageDot)) {
        return this.$message.error('页面打点只能是英文字符！')
      }

      if (this.pageContent.showCouponPop){
        if (this.pageContent.couponPopList.length===0){
          return this.$message.error('挽留弹窗，至少添加一组配置！')
        }
        let connectIds = this.pageContent.couponPopList.map(a => a.connectId)
        let s=new Set(connectIds)
        if (s.size<connectIds.length){
          return this.$message.error('挽留弹窗不能重复关联同一个组件！')
        }
        for (let item of this.pageContent.couponPopList){
          if (!item.connectId){
            return this.$message.error('挽留弹窗配置不正确，组件未关联！')
          }
          if (item.titleType===2 && !item.titleContent){
            return this.$message.error('挽留弹窗配置不正确，自定义标题未填写！')
          }
        }

        let componentIdList=list.map(a => a._id)
        for (let i=0;i<connectIds.length;i++){
          if (!componentIdList.includes(connectIds[i])){
            return this.$message.error(`挽留弹窗配置不正确，关联的${connectIds[i].substring(connectIds[i].length-4)}组件不存在！`)  
          }
        }

      }

      window.scrollTo(0, 0)
      document.querySelector('.mainBg').scrollTo(0, 0)
      loadingInstance = Loading.service({
        background: 'rgba(0,0,0,0.75)',
        fullscreen: true,
        text:'正在保存，请稍后……'
      })
      _this.setIsSaving(true)
      setTimeout(function () {
        // ------------截图-----------
        _this
          .capturePic()
          .then((canvas) => {
            _this.setIsSaving(false)
            loadingInstance.text='截图完成'
            let file = _this.dataURLtoFile(canvas.toDataURL())
            let param = new FormData()
            let picName = new Date().getTime() + '.png'
            param.append('file', file, picName)
            loadingInstance.text='上传截图'
            PageServer.uploadPicture(param)
              .then((res) => {
                _this.primaryPictureUrl = res.data
                _this.submitSave(type)
              })
              .catch(() => {
                loadingInstance.close()
              })
          })
          .catch(() => {
            // 截图失败，仍然提交数据
            _this.setIsSaving(false)
            _this.primaryPictureUrl = ''
            _this.submitSave(type)
          })
        // --------------------------
      }, 500)
     
    },
    dataURLtoFile (dataurl, filename) {
      // 将base64转换为文件
      let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: mime })
    },
    submitSave (type) {
      let _this = this
      let requestUrl =
        tool.getUrlParam('type') === '1' || _this.saveTimes > 0
          ? '/activity/updateActivityInfoNew'
          : '/activity/saveActivityInfoNew'
      let content = JSON.parse(JSON.stringify(_this.pageContent))
      loadingInstance.text='保存数据……'
      PageServer.queryDetail({
        activityCode: tool.getUrlParam('activityCode'),
      })
        .then((res) => {
          if (res.flag === 'S') {
            content.activityStatus = res.data.activityStatus
            _this.saveComponentsExtraParamsToDb(type, content, requestUrl)
          } else {
            _this.$message.error(res.msg)
          }
        })
        .catch((err) => {
          loadingInstance.close()
          _this.$message.error(err)
        })
    },
    saveComponentsExtraParamsToDb (type, content, requestUrl) {
      let _this = this
      // 特定组件的特殊数据，需要保存到数据库
      let mslist = content.componentList.filter(
        (a) => a.code === 'SecKillModule'
      )
      let paras = mslist.map((a) => {
        return {
          activityCode: tool.getUrlParam('activityCode'),
          moduleCode: a._id,
          effectiveTime: a.beginTime,
          startDate: a.startDate,
          endDate: a.endDate
        }
      })

      PageServer.addActivityModuleInfo({ moduleList: paras }).then(() => {
        _this.saveData(type, content, requestUrl)
      }).catch(() => {
        alert('保存参数出错！')
        loadingInstance.close()
      })

    },
    updateFields (content) {
      // 为了兼容老的活动，防止修改老的活动背景等参数无效,后续可以去掉
      if (!content.ruleButton) {
        this.editPage({
          field: 'ruleButton',
          value: {
            show: content.showRule ? content.showRule : false,
            text: content.ruleText ? content.ruleText : '',
            rule: {}
          }
        })
      }
      if (!content.background) {
        let data = {
          bgType: !content.bgType ? 1 : 2,
          bgStartColor: content.bgStartColor,
          bgEndColor: content.bgEndColor,
          bgMidColor: content.bgMidColor,
          bgStartPosition: !content.bgStartPosition ? 0 : content.bgStartPosition,
          bgMidPosition: !content.bgMidPosition ? 50 : content.bgMidPosition,
          bgEndPosition: !content.bgEndPosition ? 100 : content.bgEndPosition,
        }
        this.editPage({
          field: 'background',
          value: data
        })
      }
    },
    saveData (type, content, requestUrl) {
      let _this = this
      let clist = content.componentList
      for (let i = 0; i < clist.length; i++) {
        if (clist[i].code === 'ElevatorModule') {
          clist[i].selectedTab = 0
        }
      }
      console.log(content)
      content.title = _this.baseData.title
      content.pageDot = _this.baseData.pageDot
      let requestData = {
        itemCode: tool.getUrlParam('project'),
        primaryPictureUrl: _this.primaryPictureUrl,
        activityTitle: _this.baseData.title,
        pageDot: _this.baseData.pageDot,
        activityContent: JSON.stringify(content),
        activityCode: _this.baseData.activityCode,
      }

      post(requestUrl, requestData)
        .then((res) => {
          loadingInstance.close()
          if (res.flag === 'S') {
            _this.$message({
              message: '保存成功',
              type: 'success',
            })
            this.lastData =JSON.stringify(this.pageContent)
            _this.saveTimes++
          } else {
            _this.$message.error('保存失败')
          }
        })
        .catch(() => {
          loadingInstance.close()
        })
    },
    titleChanged (val) {
      this.editPage({
        _id: this.selectedComponent._id,
        field: 'title',
        value: val
      })
    },
    refreshCdn () {
      // 只有生产环境才需要刷CDN
      if (this.$URLS.stgEnv!=='pro') {
        return
      }
      let data = {
        'paths':
          [`${this.$URLS.CDN_HOST}/lego/`],
        'urls': [`${this.$URLS.CDN_HOST}/lego/${this.baseData.activityCode}.json`]
      }
      post('/cdn/refresh-url', data).then().catch(() => {
        this.$message.error('刷新CDN失败！')
      })
    },
    dotChanged (val) {
      this.editPage({
        _id: this.selectedComponent._id,
        field: 'pageDot',
        value: val
      })
    },
  }
}
</script>

<style lang="less">
.wait-loading{
  font-size: 42px;
}
html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;

  -webkit-scrollbar {
    -webkit-appearance: none;
    width: 3px;
    background-color: #f5f5f5;
  }
}


body.black {
  background: #eee;
  #app {
    height: 100%;
  }
  .builder {
    height: 100%;
  }
}
.backBtn {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}
.tool-btn {
    float: left;
    margin-left: 30px;
    cursor: pointer;
    text-align: center;

    img {
      width: 25px;
      height: 25px;
    }
  }
.tool-block {
  
  .tool-name {
    margin-top: -13px;
  }
}
.right-mode-block {
  position: absolute;
  width: 100px;
  right: 390px;
  z-index: 99;
  margin-top:5px
}
.right-mode-block .item {
  border: 1px solid #ccc;
  padding: 5px;
  margin-top: 5px;
  cursor: pointer;
}
.right-mode-block .on {
  background-color: #409eff;
  color: white;
}
.right-mode-block .noton {
  background-color: white;
}

.tool-scale-block {
  .tool-btn {
    float: left;
    margin-left: 20px;
    cursor: pointer;
    text-align: center;

    img {
      width: 15px;
      height: 15px;
    }
  }

  .tool-name {
    margin-top: -6px;
  }
}
.input-scale {
  .el-input__inner {
    width: 80px;
    text-align: center;
  }
}
.topBar {
  height: 55px !important;
  padding: 10px 20px 10px 20px !important;
  margin-bottom: 10px;
  border-bottom: 1px solid #ccc;
  background: white;
  position: sticky;
  top: 0;
  z-index: 20;
  .el-form-item__label {
    color: black;
  }
  .el-button--mini {
    padding: 7px 10px;
  }
}
.previewBtn {
  margin: 0 10px;
}
.loadingQr {
  text-align: center;
  font-size: 40px;
}
#dashboard {
  display: flex;
  // flex-direction: column;
  .leftBar {
    width: 300px;
    margin-right: 10px;
  }
  .rightBar {
    
    width: 360px;
    margin-left: 10px;
    overflow-x:hidden ;
    margin-right: 5px;
  }
  .mainScreen {
    min-width: 420px;
    .mainPage {
      min-width: 420px;
      display: flex;
      justify-content: center;
      > div {
        min-width: 420px;
      }
    }
    flex: 1;
  }

  .mainPage::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 3px;
    // background-color: #ccc;
  }

  .mainPage::-webkit-scrollbar-thumb {
    background: #f5f7fa;
  }
}
.headerTopBar {
  height:80px;
  background:#fff;
  display:flex;
  align-items: center;
  box-shadow: 2px 2px 2px 1px rgba(250, 84, 28, 0.1);
  justify-content: space-between;
  width: 100vw;
  .one_left {
    margin-left: 20px;
  }
  .center_inner {
    margin-left: 250px;
  }
  .one_right {
    margin-right: 100px;
  }


}
</style>
